Custom attributes
Since most primitives of Graphics are Javascript functions, one can extend the set of their properties / attributes modifiers (aka RGBColor, Opacity and etc) by writing a WLJS Functions.
Group modifier
The easiest example will be making something similar to Translate, which creates an SVG group and evaluates all children within a new group. By accessing env
object we can interact with a canvas and properties of the children.
Animated Rainbow stroke
Let's define our function using Javascript cells
.js
core.RainboxStroke = async (args, env) => {
const group = env.svg.append("g");
env.local.group = group;
let hue = 0;
let frame = 0;
function animateColor() {
if (frame % 2 === 0) {
hue = (hue + 4) % 360;
group.style('color', `hsl(${hue}, 100%, 50%)`);
}
frame++;
env.local.uid = requestAnimationFrame(animateColor);
}
animateColor();
//apply special SVG attribute value
//that all nested elements can inherit color of the group
await interpretate(args[0], {...env, svg: group, color:'currentColor', stroke:'currentColor'});
return group;
}
core.RainboxStroke.destroy = (args, env) => {
cancelAnimationFrame(env.local.uid);
env.local.group.remove();
}
core.RainboxStroke.virtual = true
core.RainboxStroke = async (args, env) => { const group = env.svg.append("g"); env.local.group = group; let hue = 0; let frame = 0; function animateColor() { if (frame % 2 === 0) { hue = (hue + 4) % 360; group.style('color', `hsl(${hue}, 100%, 50%)`); } frame++; env.local.uid = requestAnimationFrame(animateColor); } animateColor(); //apply special SVG attribute value //that all nested elements can inherit color of the group await interpretate(args[0], {...env, svg: group, color:'currentColor', stroke:'currentColor'}); return group; } core.RainboxStroke.destroy = (args, env) => { cancelAnimationFrame(env.local.uid); env.local.group.remove(); } core.RainboxStroke.virtual = true
Here we can apply it directly to Line, Text, Disk or any other primitives or group of primitives which use stroke or fill color
Graphics[{
RegularPolygon[4],
RainboxStroke[{
RegularPolygon[3],
Translate[Rotate[Text[Style["Hello World", FontSize->20], {0,0}], 45Degree],{0.4,0.4}]
}]
}]
The result:
(*VB[*)(Graphics[{RegularPolygon[4], RainboxStroke[{RegularPolygon[3], Translate[Rotate[Text[Style["Hello World", FontSize -> 20], {0, 0}], 45*Degree], {0.4, 0.4}]}]}])(*,*)(*"1:eJyNT0sOwiAUrN9ojK48gB7AM7gx6sKFKU1cU32tLyLPAE1ab6I38zZCsZi4ksXAZOYNb+YpxVkriiLdtbAlcfJsYGGj+O2MR521G32H2nh9YiGGvBBc7UlUOUl0Bi+OnchRplQyo+gCfyZ0XEJtHVpIFJdacPOZ7js/mcBdWgKl8axngZlKABu5HiAEzQ6kbJ1gjgsBda81ScPwDjgN/zWrob2jGr6xCV5B46LZYQW5gp9G6vlw57UMjzfTIU+7"*)(*]VB*)